package com.lcc.trans.controller;

import com.lcc.trans.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;

@RestController
@Slf4j
@RequestMapping("/trans")
public class TransController {
    @Autowired
    private UserService userService;

    /**
     * 正常操作，没有抛出异常，会进行事务的提交，不会进行回滚
     */
    @Transactional
    @RequestMapping("/registry")
    public String registry(String userName,String password){
        Integer result = userService.insertUser(userName,password);
        log.info("用户插入成功,result:" + result);
        return "注册成功";
    }

    /**
     * 抛出异常情况,没有捕获，发生回滚
     * 程序报错没有处理
     */
    @Transactional
    @RequestMapping("/registry2")
    public String registry2(String userName,String password){
        Integer result = userService.insertUser(userName,password);
        log.info("用户插入成功,result:" + result);
        int a = 10/0;
        return "注册成功";
    }

    /**
     * 程序报错，异常被获取，此时会进行事务提交
     */
    @Transactional
    @RequestMapping("/registry3")
    public String registry3(String userName,String password){
        Integer result = userService.insertUser(userName,password);
        log.info("用户插入成功,result:" + result);
        try {
            int a = 10/0;
        }catch (Exception e){
            log.info("程序报错");
        }
        return "注册成功";
    }

    /**
     * 程序报错，异常被获取，但是还是会抛出异常
     * 事务回滚
     */
    @Transactional
    @RequestMapping("/registry4")
    public String registry4(String userName,String password){
        Integer result = userService.insertUser(userName,password);
        log.info("用户插入成功,result:" + result);
        try {
            int a = 10/0;
        }catch (Exception e){
            log.info("程序报错");
            throw e;
        }
        return "注册成功";
    }

    /**
     * 程序报错，手动实现事务回滚
     */
    @Transactional
    @RequestMapping("/registry5")
    public String registry5(String userName,String password){
        Integer result = userService.insertUser(userName,password);
        log.info("用户插入成功,result:" + result);
        try {
            int a = 10/0;
        }catch (Exception e){
            log.info("程序报错");
            //TransactionAspectSupport.currentTransactionStatus():获取当前事务状态
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//把当前事务回滚
        }
        return "注册成功";
    }

    @Transactional
    @RequestMapping("/registry6")
    public String registry6(String userName,String password) throws IOException {
        Integer result = userService.insertUser(userName,password);
        log.info("用户插入成功,result:" + result);
        try {
            int a = 10/0;
        }catch (Exception e){
            log.info("程序报错");
            //非运行异常，此时抛出事务不会进行事务回滚
            throw new IOException();
            //运行时异常，此时抛出会进行事务的回滚，Transactional默认对Error和运行时异常起作用，
            // 如果要让其对其他异常起作用，通过registry7设置rollBackFor属性
//            throw new NullPointerException();
        }
        return "注册成功";
    }

    @Transactional(rollbackFor = {Exception.class,Error.class})
    @RequestMapping("/registry7")
    public String registry7(String userName,String password) throws IOException {
        Integer result = userService.insertUser(userName,password);
        log.info("用户插入成功,result:" + result);
        try {
            int a = 10/0;
        }catch (Exception e){
            log.info("程序报错");
            //该异常为非运行时异常，本来Transactional不会对其起作用发生回滚的，但是通过设置@Transactional的rollBackFor属性可以修改
            throw new IOException();
        }
        return "注册成功";
    }
}
